/*
 * Copyright (C) 2015 Daniel Uppenkamp
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.maurersmarbles;

import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Daniel Uppenkamp
 */
public class GameState {

    /**
     * The card deck.
     */
    protected CardDeck cardDeck;
    /**
     * The player that is currently the dealer.
     */
    protected int dealer;
    /**
     * The index of the user's marble color in the GameLogic.MARBLE_COLORS
     * array.
     */
    protected int userMarbleColorIndex = 0;
    /**
     * The user player number.
     */
    protected int userPlayerNumber = 0;
    /**
     * The players.
     */
    protected final List<Player> players = new ArrayList();
    /**
     * The status of the game.
     */
    protected String status;

    /**
     * Creates a new GameState.
     */
    public GameState() {
        initialize();
    }

    /**
     * Creates a new GameState.
     *
     * @param gameState the game state to copy
     */
    public GameState(GameState gameState) {

        Preconditions.checkNotNull(gameState, "Null game state");

        this.cardDeck = new CardDeck(gameState.cardDeck);

        this.dealer = gameState.dealer;

        for (Player player : gameState.getPlayers()) {
            this.players.add(new Player(player));
        }

        this.userMarbleColorIndex = gameState.userMarbleColorIndex;
        this.userPlayerNumber = gameState.userPlayerNumber;

    }

    /**
     * Returns the card deck.
     *
     * @return the card deck
     */
    public CardDeck getCardDeck() {
        return cardDeck;
    }

    /**
     * Sets the card deck.
     *
     * @param cardDeck the card deck
     */
    public void setCardDeck(CardDeck cardDeck) {
        Preconditions.checkNotNull(cardDeck, "Null card deck");
        this.cardDeck = cardDeck;
    }

    /**
     * Returns the player that is currently the dealer.
     *
     * @return the player that is currently the dealer
     */
    public int getDealer() {
        return dealer;
    }

    /**
     * Sets the player that is currently the dealer
     *
     * @param dealer the player that is currently the dealer
     */
    public void setDealer(int dealer) {
        this.dealer = dealer;
    }

    /**
     * Returns the players.
     *
     * @return the players
     */
    public List<Player> getPlayers() {
        return players;
    }

    /**
     * Returns the status to display on the screen.
     *
     * @return the status to display on the screen
     */
    public String getStatus() {
        return status;
    }

    /**
     * Sets the status to display on the screen.
     *
     * @param status the status to display on the screen
     */
    public void setStatus(String status) {
        this.status = status;
    }

    /**
     * Returns the index of the user's marble color in the
     * GameLogic.MARBLE_COLORS array.
     *
     * @return the index of the user's marble color in the
     * GameLogic.MARBLE_COLORS array
     */
    public int getUserMarbleColorIndex() {
        return userMarbleColorIndex;
    }

    /**
     * Sets the index of the user's marble color in the GameLogic.MARBLE_COLORS
     * array.
     *
     * @param userMarbleColorIndex the index of the user's marble color in the
     * GameLogic.MARBLE_COLORS array
     */
    public void setUserMarbleColorIndex(int userMarbleColorIndex) {
        this.userMarbleColorIndex = userMarbleColorIndex;
    }

    /**
     * Returns the user player number.
     *
     * @return the user player number
     */
    public int getUserPlayerNumber() {
        return userPlayerNumber;
    }

    /**
     * Sets the user player number.
     *
     * @param userPlayerNumber the user player number
     */
    public void setUserPlayerNumber(int userPlayerNumber) {
        this.userPlayerNumber = userPlayerNumber;
    }

    /**
     * Initializes the game state.
     */
    protected final void initialize() {

        // a new card deck will be created when it is needed
        cardDeck = null;

        // create the players
        players.clear();
        for (int i = 0; i < GameLogic.NUMBER_OF_PLAYERS; i++) {
            players.add(new Player(i));
        }

        // set the default user marble color
        userMarbleColorIndex = 0;

        // default to no status
        status = null;

    }

    /**
     * Reinitializes the game state for a new game.
     */
    public void reinitialize() {
        initialize();
    }

}
